#ifndef __datashuttle_http_message_header_file_h__
#define __datashuttle_http_message_header_file_h__

#include <string>
#include <map>

namespace datashuttle
{

enum HttpMethod
{
	HTTP_MTD_UNKNOWN,
	HTTP_MTD_GET,
	HTTP_MTD_POST,
	HTTP_MTD_PUT,
	HTTP_MTD_DELETE,
	HTTP_MTD_HEAD,
	HTTP_MTD_OPTIONS,
	HTTP_MTD_TRACE,
	HTTP_MTD_CONNECT,
};
enum HttpProtocol
{
	HTTP_PROTO_NULL,
	HTTP_PROTO_10,
	HTTP_PROTO_11,
};

class HttpMessage
{
public:
	HttpMessage();
	virtual ~HttpMessage();

public:
	
	HttpMethod			getMethod() const;
	const std::string&	getUri() const;
	HttpProtocol		getProtocol() const;
	std::string			getHeader( const std::string& key ) const;
	bool				isBodyChunked() const;
	size_t				getBodySize() const;

	void				setUri( const std::string& uri );
	void				setProtocol( HttpProtocol p);
	void				setMethod( HttpMethod mtd);
	void				setHeader( const std::string& key, const std::string& value );
	void				removeHeader( const std::string& key );

private:
	HttpMethod		mMethod;//NOTE: method is case sensitive
	std::string		mUri;
	HttpProtocol	mProtocol;
	typedef std::map<std::string,std::string> HEADERS;
	HEADERS			mHeaders;
	size_t			mBodySize;
};

class HttpMsgParser
{
public:
	HttpMsgParser();
	virtual	~HttpMsgParser();

	HttpMessage*	parse( const char* data, size_t size );

	virtual bool	onBadFormat( const char* reason );
public:
	class LineParser
	{
	public:
		LineParser( const char* data, size_t size, std::string& mReserved );
	public:

		bool	getNextline( const char*& p, size_t& size );

	private:
		const char*&	mpData;
		size_t&			mSize;
		std::string&	mRefReserved;
		std::string		mReserved;
	};

	class LineSplitter
	{
	public:
		LineSplitter( const char* data, size_t size );

		void		setDilemeter( const char* dilemeter, size_t dileSize, const char* trimChar, size_t trimSize );

		const char* nextpart( size_t& size  );

	protected:

		size_t		findsubstr( const char* p, size_t sz );

		//find any character of 'p'
		size_t		findfirstnotof( const char* p, size_t sz );
		size_t		findlastnotof( const char* p, size_t sz );

	private:
		const char*		mpData;
		size_t			mSize;
		const char*		mDilemeter;
		size_t			mDileSize;
		const char*		mTrimStr;
		size_t			mTrimSize;
	};
protected:

	HttpMethod	parseHttpMethod( const char* p, size_t sz );

	bool		parseStartLine( const char* p, size_t sz);
	
	bool		parseHeader( const char* p, size_t sz);

private:
	enum PARSE_STATE
	{
		STATE_FIRSTLINE,
		STATE_HEADER,
		STATE_BODY,
		STATE_DONE
	};
	
	PARSE_STATE		mParseState;
	std::string		mReserved;
	HttpMessage*	mHttpMsg;
	size_t			mConsumedBodySize;
};

}//namespace datashuttle
#define//__datashuttle_http_message_header_file_h__ 

